package base.thread.locks;

import java.util.concurrent.CyclicBarrier;

public class BenchmarkTest {
	
	private Counter counter;
	private CyclicBarrier barrier;
	private int threadNum;
	private int loopNum;
	private String testName;
	
	public BenchmarkTest(Counter counter,int threadNum,int loopNum,String testName){
		this.counter=counter;
		this.threadNum=threadNum;
		this.loopNum=loopNum;
		this.testName=testName;
		barrier=new CyclicBarrier(threadNum+1);
	}
	
	public static void main(String[] args) throws Exception{
		int threadNum=200;
		int loopNum=1000;
		new BenchmarkTest(new SynchronizedBenChmarkDemo(), threadNum, loopNum, "内部锁").test();
		new BenchmarkTest(new ReenTrantLockUnfairBeanChmarkDemo(), threadNum, loopNum, "不公平重入锁").test();
		new BenchmarkTest(new ReentrantLockFairBeanchmarkDemo(), threadNum, loopNum, "公平重入锁").test();
	}
	
	public void test() throws Exception{
		try {
			for(int i=0;i<threadNum;i++){
				new TestThread(counter, loopNum).start();
			}
			long start=System.currentTimeMillis();
			barrier.await();
			barrier.await();
			long end=System.currentTimeMillis();
			System.out.println(this.testName+" count value:"+counter.getValue());
			System.out.println(this.testName+" cost time:"+ (end-start)+" mill second");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	class TestThread extends Thread{
		int loopNum=100;
		private Counter counter;
		public TestThread(final Counter counter,int loopNum){
			this.counter=counter;
			this.loopNum=loopNum;
		}
		public void run(){
			try{
				barrier.await();
				for(int i=0;i<loopNum;i++){
					counter.increment();
				}
				barrier.await();
			}catch (Exception e) {
			}
		}
	}
}
